machine_to_phys_mapping[virt_to_phys(d->arch.mm_perdomain_pt) >>
PAGE_SHIFT] = INVALID_M2P_ENTRY;
ed->arch.perdomain_ptes = d->arch.mm_perdomain_pt;
+#if 0 /* don't need this yet, but maybe soon! */
+ ed->arch.guest_vtable = linear_l2_table;
+ ed->arch.shadow_vtable = shadow_linear_l2_table;
+#endif
#ifdef __x86_64__
d->arch.mm_perdomain_l2 = (l2_pgentry_t *)alloc_xenheap_page();
&idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t));
- ed->arch.monitor_table = mk_pagetable(mpfn << PAGE_SHIFT);
-
mpl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
mk_l2_pgentry((__pa(d->arch.mm_perdomain_pt) & PAGE_MASK)
| __PAGE_HYPERVISOR);
+ ed->arch.monitor_table = mk_pagetable(mpfn << PAGE_SHIFT);
+ ed->arch.monitor_vtable = mpl2e;
+
phys_table = (l2_pgentry_t *)
map_domain_mem(pagetable_val(ed->arch.phys_table));
memcpy(d->arch.mm_perdomain_pt, phys_table,
L1_PAGETABLE_ENTRIES * sizeof(l1_pgentry_t));
unmap_domain_mem(phys_table);
- unmap_domain_mem(mpl2e);
}
/*
ASSERT( pagetable_val(ed->arch.monitor_table) );
- mpl2e = (l2_pgentry_t *)
- map_domain_mem(pagetable_val(ed->arch.monitor_table));
+ mpl2e = ed->arch.monitor_vtable;
+
/*
* First get the pfn for hl2_table by looking at monitor_table
*/
free_domheap_page(&frame_table[mpfn]);
ed->arch.monitor_table = mk_pagetable(0);
+ ed->arch.monitor_vtable = 0;
}
static int vmx_final_setup_guest(struct exec_domain *ed,
#ifdef CONFIG_VMX
-static inline void vmx_update_shadow_state(
- struct exec_domain *ed, unsigned long gmfn, unsigned long smfn)
-{
-
- l2_pgentry_t *mpl2e = 0;
- l2_pgentry_t *gpl2e, *spl2e;
-
- /* unmap the old mappings */
- if ( ed->arch.shadow_vtable )
- unmap_domain_mem(ed->arch.shadow_vtable);
- if ( ed->arch.guest_vtable )
- unmap_domain_mem(ed->arch.guest_vtable);
-
- /* new mapping */
- mpl2e = (l2_pgentry_t *)
- map_domain_mem(pagetable_val(ed->arch.monitor_table));
-
- // mafetter: why do we need to keep setting up shadow_linear_pg_table for
- // this monitor page table? Seems unnecessary...
- //
- mpl2e[l2_table_offset(SH_LINEAR_PT_VIRT_START)] =
- mk_l2_pgentry((smfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
- __flush_tlb_one(SH_LINEAR_PT_VIRT_START);
-
- spl2e = (l2_pgentry_t *)map_domain_mem(smfn << PAGE_SHIFT);
- gpl2e = (l2_pgentry_t *)map_domain_mem(gmfn << PAGE_SHIFT);
- memset(spl2e, 0, L2_PAGETABLE_ENTRIES * sizeof(l2_pgentry_t));
-
- ed->arch.shadow_vtable = spl2e;
- ed->arch.guest_vtable = gpl2e; /* expect the guest did clean this up */
- unmap_domain_mem(mpl2e);
-}
-
static inline unsigned long gva_to_gpte(unsigned long gva)
{
unsigned long gpde, gpte, pfn, index;
if ( unlikely(smfn == 0) )
smfn = shadow_l2_table(d, gmfn);
-#ifdef CONFIG_VMX
- else if ( shadow_mode_translate(ed->domain) )
- vmx_update_shadow_state(ed, gmfn, smfn);
-#endif
ed->arch.shadow_table = mk_pagetable(smfn<<PAGE_SHIFT);
- if ( !shadow_mode_external(ed->domain) )
- // mafetter: why do we need to keep overwriting
- // ed->arch.monitor_table? Seems unnecessary...
- //
- ed->arch.monitor_table = ed->arch.shadow_table;
+ if ( shadow_mode_translate(ed->domain) )
+ {
+ l2_pgentry_t *gpl2e, *spl2e;
+
+ if ( ed->arch.guest_vtable )
+ unmap_domain_mem(ed->arch.guest_vtable);
+ if ( ed->arch.shadow_vtable )
+ unmap_domain_mem(ed->arch.shadow_vtable);
+
+ gpl2e = ed->arch.guest_vtable =
+ map_domain_mem(pagetable_val(ed->arch.guest_table));
+ spl2e = ed->arch.shadow_vtable =
+ map_domain_mem(pagetable_val(ed->arch.shadow_table));
+
+ if ( shadow_mode_external(ed->domain ) )
+ {
+ l2_pgentry_t *mpl2e = ed->arch.monitor_vtable;
+ unsigned long old_smfn;
+ unsigned sh_l2offset = l2_table_offset(SH_LINEAR_PT_VIRT_START);
+
+ old_smfn = l2_pgentry_val(mpl2e[sh_l2offset]) >> PAGE_SHIFT;
+ if ( old_smfn != smfn )
+ {
+ mpl2e[sh_l2offset] =
+ mk_l2_pgentry((smfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
+ local_flush_tlb();
+ }
+ }
+
+ if ( ed->arch.arch_vmx.flags )
+ {
+ // Why is VMX mode doing this?
+ memset(spl2e, 0, L2_PAGETABLE_ENTRIES * sizeof(l2_pgentry_t));
+ }
+ }
}
static inline void update_pagetables(struct exec_domain *ed)
__update_pagetables(ed);
shadow_unlock(ed->domain);
}
+ if ( !shadow_mode_external(ed->domain) )
+ {
#ifdef __x86_64__
- else if ( !(ed->arch.flags & TF_kernel_mode) )
- // mafetter: why do we need to keep overwriting
- // ed->arch.monitor_table? Seems unnecessary...
- //
- ed->arch.monitor_table = ed->arch.guest_table_user;
+ if ( !(ed->arch.flags & TF_kernel_mode) )
+ ed->arch.monitor_table = ed->arch.guest_table_user;
+ else
#endif
- else
- // mafetter: why do we need to keep overwriting
- // ed->arch.monitor_table? Seems unnecessary...
- //
- ed->arch.monitor_table = ed->arch.guest_table;
+ if ( shadow_mode_enabled(ed->domain) )
+ ed->arch.monitor_table = ed->arch.shadow_table;
+ else
+ ed->arch.monitor_table = ed->arch.guest_table;
+ }
}
#if SHADOW_DEBUG